<?php

namespace Biz\service;

use Biz\model\DbStatJson;
use Biz\model\trade\Order as mOrder;
use Biz\model\trade\OrderGoods as mOrderGoods;
use Biz\pockets\constInterface\EventTag;
use Biz\cache\DataStat as cDataStat;
use Doraemon\tools\Log as tLog;
/**
 * @deprecated
 */
class Datastat implements EventTag
{
    /**
     * @desc 错误日志
     * @param string $title 日志名称
     * @param array $params 存储参数
     * @return mixed
     */
    public static function errorLog($title, array $params = [])
    {
        tLog::warning('商城后台数据展示::' . $title, $params);
    }

    /**
     * @desc 信息日志
     * @param string $title 日志名称
     * @param array $params 存储参数
     * @return mixed
     */
    public static function infoLog($title, array $params = [])
    {
        tLog::info('商城后台数据展示记录::' . $title, $params);
    }

    public static function indexData()
    {
        return [
            '生成订单数'     => cDataStat::sCardBase(cDataStat::KEY_TYPE_CREATE, 0),
            '生成订单商品数' => cDataStat::getByBase(cDataStat::KEY_TYPE_CREATE_GOODS, 0),
            '生成订单金额'   => self::formatAmount(cDataStat::getByBase(cDataStat::KEY_TYPE_CREATE_AMOUNT, 0)),
            '支付订单数'     => cDataStat::sCardBase(cDataStat::KEY_TYPE_PAY, 0),
            '支付订单商品数' => cDataStat::getByBase(cDataStat::KEY_TYPE_PAY_GOODS, 0),
            '支付订单金额'   => self::formatAmount(cDataStat::getByBase(cDataStat::KEY_TYPE_PAY_AMOUNT, 0)),
            '首单用户数'     => cDataStat::sCardBase(cDataStat::KEY_TYPE_FIRST_CREATE_MEMBER, 0),
            '首单订单商品数' => cDataStat::getByBase(cDataStat::KEY_TYPE_FIRST_CREATE_GOODS, 0),
            '首单订单金额'   => self::formatAmount(cDataStat::getByBase(cDataStat::KEY_TYPE_FIRST_CREATE_AMOUNT, 0)),
            '总下单用户数'   => cDataStat::sCardBase(cDataStat::KEY_TYPE_CREATE_MEMBER, 0),
            '发货前退款订单数' => cDataStat::sCardBase(cDataStat::KEY_TYPE_BEFORE_REFUND, 0),
            '发货后退款订单数' => cDataStat::sCardBase(cDataStat::KEY_TYPE_AFTER_REFUND, 0),
        ];
    }

    /**
     * @desc 首页列表数据
     * @return mixed
     */
    public static function indexListData()
    {
        $top = 15;
        //实际销售数量
        $salesBase = cDataStat::zRangeByBase(cDataStat::KEY_TYPE_PAY_SKU_RANK);
        $salesTopBase = array_slice($salesBase, 0, $top, true);

        //实际销售金额
        $salesAmountBase = cDataStat::zRangeByBase(cDataStat::KEY_TYPE_PAY_SKU_AMOUNT_RANK);
        $salesAmountTopBase = array_slice($salesAmountBase, 0, $top, true);

        //购买用户数
        $buyMemberBase = cDataStat::zRangeByBase(cDataStat::KEY_TYPE_PAY_SKU_USER);

        //下单商品数量
        $buyNumBase = cDataStat::zRangeByBase(cDataStat::KEY_TYPE_SKU_RANK);

        //下单金额
        $buyAmountBase = cDataStat::zRangeByBase(cDataStat::KEY_TYPE_SKU_AMOUNT_RANK);

        //商品goods_id集合
        $goodsIds = array_unique(array_merge(array_keys($salesTopBase), array_keys($salesAmountTopBase)));
        $info = Sku::dataStatGoodsFormat($goodsIds);

        //查询pv,uv,add_cart_count
        $spuOtherData = DbStatJson::getInfoBySpuIds($goodsIds);
        $spuOtherData = $spuOtherData ? array_column($spuOtherData, null, 'spu_id') : [];
        
        //初始化结构
        $item = [
            'name'          => '-',//	商品名称
            'category_name' => '-',//前台一级商品分类
            'second_category_name' => '-',//前台二级商品分类
            'pay_num'       => '-',//实际销售数量
            'pay_amount'    => '-',//实际销售金额
            'add_cart_member' => '-',//加购用户数
            'buy_num'       => '-',//下单商品数量
            'buy_amount'    => '-',//下单金额
            'buy_member'    => '-',//购买用户数
            'uv'            => '-',//商品曝光-uv
            'pv'            => '-',//商品曝光-pv
        ];
        //销量排行
        $salesTop = self::formatIndex($salesTopBase, $item, $info, $salesBase, $salesAmountBase, $buyNumBase, $buyAmountBase, $buyMemberBase, $spuOtherData);

        //销售额排行
        $salesAmountTop = self::formatIndex($salesAmountTopBase, $item, $info, $salesBase, $salesAmountBase, $buyNumBase, $buyAmountBase, $buyMemberBase, $spuOtherData);

        return compact('salesTop', 'salesAmountTop', 'goodsIds', 'info');
    }

    private static function formatAmount($amount)
    {
        return number_format(bcdiv($amount, 100, 2), 2);
    }

    private static function formatIndex($base, $item, $info, $salesBase, $salesAmountBase, $buyNumBase, $buyAmountBase, $buyMemberBase, $spuOtherData)
    {
        $response = [];
        foreach ($base as $id => $num) {
            $baseInfo = isset($info[$id]) ? $info[$id] : [];
            $baseInfo += $item;
            $baseInfo['pay_num'] = $salesBase[$id];
            $baseInfo['pay_amount'] = self::formatAmount($salesAmountBase[$id]);
            $baseInfo['buy_num'] = isset($buyNumBase[$id]) ? $buyNumBase[$id] : 0;
            $baseInfo['buy_amount'] = self::formatAmount(isset($buyAmountBase[$id]) ? $buyAmountBase[$id] : 0);
            $baseInfo['buy_member'] = isset($buyMemberBase[$id]) ? $buyMemberBase[$id] : 0;
            if (isset($spuOtherData[$id])) {
                $baseInfo['add_cart_member'] = $spuOtherData[$id]['add_cart_count'];
                $baseInfo['pv'] = $spuOtherData[$id]['pv'];
                $baseInfo['uv'] = $spuOtherData[$id]['uv'];
            }
            $response[] = $baseInfo;
        }
        return $response;
    }

    /**
     * @desc 创建订单处理
     * @param int $uid 用户id
     * @param string $order_parent_no 父订单号
     * @param array $order_list 订单列表
     * @param string $addTime 创建订单时间
     * @return mixed
     */
    public static function createOrder($uid, $order_parent_no, $order_list, $addTime)
    {
        $incr = cDataStat::sAddBase(cDataStat::KEY_TYPE_CREATE, $order_parent_no);//生成订单数
        if ($incr) {//防止重复添加
            $goodsCount = 0;
            $orderAmount = 0;
            if ($order_list) {
                //子订单列表
                foreach ($order_list as $v) {
                    if (!empty($v['sku_list']) && is_array($v['sku_list'])) {
                        //购买商品列表
                        foreach ($v['sku_list'] as $order_goods) {
                            $goods_id = $order_goods['goods_id'];
                            $sku_id = $order_goods['sku_id'];
                            $pay_amount = $order_goods['pay_amount'] * 100;
                            $buy_num = $order_goods['buy_num'];
                            $goodsCount += $buy_num;
                            $orderAmount = bcadd($pay_amount, $orderAmount);

                            //下单商品数量
                            cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_RANK, $buy_num, $goods_id);

                            //下单金额
                            cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_AMOUNT_RANK, $pay_amount, $goods_id);

                            //下单用户数
                            if (cDataStat::sAddBase(cDataStat::KEY_TYPE_SKU_USER_MAP, $uid, $goods_id)) {
                                cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_USER, 1, $goods_id);
                            }
                        }
                    }
                }
            }
            cDataStat::incrByBase(cDataStat::KEY_TYPE_CREATE_GOODS, $goodsCount);//生成订单商品数
            cDataStat::incrByBase(cDataStat::KEY_TYPE_CREATE_AMOUNT, $orderAmount);//生成订单金额
            cDataStat::sAddBase(cDataStat::KEY_TYPE_CREATE_MEMBER, $uid);//总下单用户数

            if (self::isFirstUser($uid, $addTime)) {
                cDataStat::sAddBase(cDataStat::KEY_TYPE_FIRST_CREATE_MEMBER, $uid);//首单用户数
                cDataStat::incrByBase(cDataStat::KEY_TYPE_FIRST_CREATE_GOODS, $goodsCount);//首单订单商品数
                cDataStat::incrByBase(cDataStat::KEY_TYPE_FIRST_CREATE_AMOUNT, $orderAmount);//首单订单金额
            }
            self::infoLog('创建订单处理', compact('uid', 'order_parent_no', 'order_list', 'addTime'));
        }
    }

    /**
     * @desc 申请退款处理
     * @param string $order_no 订单no
     * @return mixed
     * @throws \Exception
     */
    public static function refundOrder($order_no)
    {
        //查询订单的发货状态
        $order = mOrder::getOrderByOrderNo($order_no);
        if (!$order) {
            throw new \Exception('订单号不存在,order_no:' . $order_no);
        }
        if (in_array($order['status'], [mOrder::STATUS_WAIT_SEND])) {
            cDataStat::addBeforeRefund($order_no);//发货前退款订单数
        } else {
            cDataStat::addAfterRefund($order_no);//发货后退款订单数
        }
        self::infoLog('申请退款处理', compact('order_no', 'order'));
    }

    /**
     * @desc 支付订单处理
     * @param $order_info_list
     * @return mixed
     */
    public static function payOrder($order_info_list)
    {
        $goodsCount = 0;
        $orderAmount = 0;
        if ($order_info_list) {
            $orderNos = [];
            foreach ($order_info_list as $value) {
                if (cDataStat::sAddBase(cDataStat::KEY_TYPE_PAY, $value['order_no'])) {//支付订单数
                    $orderNos[] = $value['order_no'];
                }
            }
            if ($orderNos) {
                $orderGoods = mOrderGoods::getOrderGoodsList($orderNos, [], '', ['order_no','buy_num','pay_amount', 'goods_id', 'uid']);
                foreach ($orderGoods as $order_goods) {
                    $uid = $order_goods['uid'];
                    $goods_id = $order_goods['goods_id'];
                    $pay_amount = $order_goods['pay_amount'] * 100;
                    $buy_num = $order_goods['buy_num'];
                    $goodsCount += $buy_num;
                    $orderAmount = bcadd($pay_amount, $orderAmount);

                    //实际销售数量
                    cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_RANK, $buy_num, $goods_id);

                    //实际销售金额
                    cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_AMOUNT_RANK, $pay_amount, $goods_id);

                    //实际购买用户数
                    if (cDataStat::sAddBase(cDataStat::KEY_TYPE_PAY_SKU_USER_MAP, $uid, $goods_id)) {
                        cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_USER, 1, $goods_id);
                    }
                }
                cDataStat::incrByBase(cDataStat::KEY_TYPE_PAY_GOODS, $goodsCount);//支付订单商品数
                cDataStat::incrByBase(cDataStat::KEY_TYPE_PAY_AMOUNT, $orderAmount);//支付订单金额
            }
        }
        self::infoLog('支付订单处理', compact('order_info_list'));
    }

    /**
     * @desc 首单用户
     * @param string $uid 用户id
     * @return mixed
     */
    static $isFirst = [];
    public static function isFirstUser($uid, $start_date)
    {
        if (!isset(self::$isFirst[$uid])) {
            $payInfos =  mOrder::getOrderInfoList([
                'GROUP' => 'uid',
                'status[!]' => [mOrder::STATUS_NORMAL],
                'pay_way[!]' => '0',
                'uid' => $uid,
                'pay_time[<]' => $start_date,
            ], [], [], false, 'uid');
            $isPayed = $payInfos ? $payInfos : [];
            self::$isFirst[$uid] = !in_array($uid, $isPayed);
        }
        return self::$isFirst[$uid];
    }

    public static function allKeys()
    {
        var_dump(cDataStat::allKeys());
    }
    public static function test()
    {
        $sku_id = array_random([2229180, 2229176, 2229174, 2229172, 2229169, 2228707, 2228705, 2228691, 2228667, 2228258, 2228217]);
        $buy_num = mt_rand(1, 5);
        $pay_amount = mt_rand(10000, 900000) * $buy_num;
        $uid = mt_rand(2250000, 3000000);


        //下单商品数量
        cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_RANK, $buy_num, $sku_id);

        //下单金额
        cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_AMOUNT_RANK, $pay_amount, $sku_id);

        //下单用户数
        if (cDataStat::sAddBase(cDataStat::KEY_TYPE_SKU_USER_MAP, $uid, $sku_id)) {
            cDataStat::zIncrByBase(cDataStat::KEY_TYPE_SKU_USER, 1, $sku_id);
        }

        cDataStat::incrByBase(cDataStat::KEY_TYPE_CREATE_GOODS, $buy_num);//生成订单商品数
        cDataStat::incrByBase(cDataStat::KEY_TYPE_CREATE_AMOUNT, $pay_amount);//生成订单金额
        cDataStat::sAddBase(cDataStat::KEY_TYPE_CREATE_MEMBER, $uid);//总下单用户数

        if (rand(0, 1)) {
            cDataStat::sAddBase(cDataStat::KEY_TYPE_FIRST_CREATE_MEMBER, $uid);//首单用户数
            cDataStat::incrByBase(cDataStat::KEY_TYPE_FIRST_CREATE_GOODS, $buy_num);//首单订单商品数
            cDataStat::incrByBase(cDataStat::KEY_TYPE_FIRST_CREATE_AMOUNT, $pay_amount);//首单订单金额
        }
        if (rand(0, 1)) {
            //实际购买用户数
            if (cDataStat::sAddBase(cDataStat::KEY_TYPE_PAY_SKU_USER_MAP, $uid, $sku_id)) {
                cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_USER, 1, $sku_id);
            }
            //实际销售数量
            cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_RANK, $buy_num, $sku_id);

            //实际销售金额
            cDataStat::zIncrByBase(cDataStat::KEY_TYPE_PAY_SKU_AMOUNT_RANK, $pay_amount, $sku_id);

            cDataStat::incrByBase(cDataStat::KEY_TYPE_PAY_GOODS, $buy_num);//支付订单商品数
            cDataStat::incrByBase(cDataStat::KEY_TYPE_PAY_AMOUNT, $pay_amount);//支付订单金额
        }

    }
}